#include "StdAfx.h"
#include "Light.h"

VAMPIRE_NAMESPACE_BEGIN

Light::Light( const TString& name, const DWORD& index ) : MovableObject(name), mIndex(index)
{
	mLightInfo.Ambient      = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
	mLightInfo.Attenuation0 = 1.0f;
	mLightInfo.Attenuation1 = 0.0f;
	mLightInfo.Attenuation2 = 0.0f;
	mLightInfo.Diffuse      = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
	mLightInfo.Direction    = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
	mLightInfo.Falloff      = 1.0f;
	mLightInfo.Phi          = PI / 3.0f;
	mLightInfo.Position     = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	mLightInfo.Range        = 1000.0f;
	mLightInfo.Specular     = D3DXCOLOR(0.6f, 0.6f, 0.6f, 1.0f);
	mLightInfo.Theta        = PI / 6.0f;

}

void Light::setType( const D3DLIGHTTYPE& type )
{
	mLightType = type;
	mLightInfo.Type = mLightType;
	resetLight();
}

void Light::setPosition( const Real& x, const Real& y, const Real& z )
{
	if(D3DLIGHT_DIRECTIONAL == mLightType)
	{
		return;
	}
	mLightInfo.Position.x = x;
	mLightInfo.Position.y = y;
	mLightInfo.Position.z = z;

	resetLight();
}

void Light::setPosition( const Vector3& pos )
{
	if(D3DLIGHT_DIRECTIONAL == mLightType)
	{
		return;
	}
	mLightInfo.Position.x = pos.mData.x;
	mLightInfo.Position.y = pos.mData.y;
	mLightInfo.Position.z = pos.mData.z;

	resetLight();
}

void Light::setDirection( const Real& x, const Real& y, const Real& z )
{
	if(D3DLIGHT_POINT == mLightType)
	{
		return;
	}

	mLightInfo.Direction.x = x;
	mLightInfo.Direction.y = y;
	mLightInfo.Direction.z = z;

	resetLight();
}

void Light::setDirection( const Vector3& dir )
{
	if(D3DLIGHT_POINT == mLightType)
	{
		return;
	}
	mLightInfo.Direction.x = dir.mData.x;
	mLightInfo.Direction.y = dir.mData.y;
	mLightInfo.Direction.z = dir.mData.z;

	resetLight();
}

void Light::setSpotlightRange( const Radian& innerAngle, const Radian& outerAngle, const Real& falloff /*= 1.0f*/ )
{
	if(D3DLIGHT_SPOT != mLightType)
	{
		return;
	}
	mLightInfo.Theta = innerAngle.mData;
	mLightInfo.Phi = outerAngle.mData;
	mLightInfo.Falloff = falloff;

	resetLight();
}

void Light::setDiffuseColour( const Real& red, const Real& green, const Real& blue )
{
	mLightInfo.Diffuse.a = 1.0f;
	mLightInfo.Diffuse.r = red;
	mLightInfo.Diffuse.g = green;
	mLightInfo.Diffuse.b = blue;

	resetLight();
}

void Light::setDiffuseColour( const D3DXCOLOR& color )
{
	mLightInfo.Diffuse = color;

	resetLight();
}

void Light::setSpecularColour( const Real& red, const Real& green, const Real& blue )
{
	mLightInfo.Specular.a = 1.0f;
	mLightInfo.Specular.r = red;
	mLightInfo.Specular.g = green;
	mLightInfo.Specular.b = blue;

	resetLight();
}

void Light::setSpecularColour( const D3DXCOLOR& color )
{
	mLightInfo.Specular.a = 1.0f;
	mLightInfo.Specular.r = color.r;
	mLightInfo.Specular.g = color.g;
	mLightInfo.Specular.b = color.b;

	resetLight();
}

void Light::setAmbientColour( const Real& red, const Real& green, const Real& blue )
{
	mLightInfo.Ambient.a = 1.0f;
	mLightInfo.Ambient.r = red;
	mLightInfo.Ambient.g = green;
	mLightInfo.Ambient.b = blue;

	resetLight();
}

void Light::setAmbientColour( const D3DXCOLOR& color )
{
	mLightInfo.Ambient.a = 1.0f;
	mLightInfo.Ambient.r = color.r;
	mLightInfo.Ambient.g = color.g;
	mLightInfo.Ambient.b = color.b;

	resetLight();
}

void Light::setEnabled( BOOL enable )
{
	BOOL enabled;
	gpDevice->GetLightEnable(mIndex, &enabled);
	if (enabled == enable)
	{
		return;
	}

	gpDevice->LightEnable(mIndex, enable);
}

void Light::setRange( const Real& range )
{
	if(D3DLIGHT_DIRECTIONAL == mLightType)
	{
		return;
	}
	mLightInfo.Range = range;
	resetLight();
}

void Light::setAttenuationFactor( const Real& a0 /*= 1.0f*/, const Real& a1 /*= 0.0f*/, const Real& a2 /*= 0.0f*/ )
{
	if(D3DLIGHT_DIRECTIONAL == mLightType)
	{
		return;
	}
	mLightInfo.Attenuation0 = a0;
	mLightInfo.Attenuation1 = a1;
	mLightInfo.Attenuation2 = a2;
	resetLight();
}

void Light::resetLight()
{
	setEnabled(FALSE);
	gpDevice->SetLight(mIndex, &mLightInfo);
	setEnabled(TRUE);
}

VAMPIRE_NAMESPACE_END